package com.usian.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.github.pagehelper.PageInfo;
import com.usian.common.dto.CourseDTO;
import com.usian.common.dto.TrainingDTO;
import com.usian.common.model.member.Member;
import com.usian.common.model.training.TrainingMember;
import com.usian.common.untils.Result;
import com.usian.common.vo.CatalogVO;
import com.usian.common.vo.CourseVO;
import com.usian.common.vo.PaperVO;
import com.usian.common.vo.TrainingVO;
import com.usian.service.CourseDetailsFeignService;
import com.usian.service.CourseFeignService;
import com.usian.service.PaperFeignService;
import com.usian.service.TrainingFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @projectName: 2210A-project1
 * @package: com.usian.controller
 * @className: TrainingController
 * @author: 莫洪维
 * @email: 1204315800@qq.com
 * @description: TODO
 * @date: 2023/8/31 18:33
 */
@RestController
@RequestMapping("/training")
public class TrainingController {

    @Autowired
    private TrainingFeignService trainingFeignService;
    @Autowired
    private CourseDetailsFeignService courseDetailsFeignService;
    @Autowired
    private CourseFeignService courseFeignService;
    @Autowired
    private PaperFeignService paperFeignService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据培训id查询试卷方法
     * @param id
     * @return 试卷集合 Result.data.key -> list
     */
    @RequestMapping(value = "/findPaper",method = RequestMethod.GET)
    public Result findPaper(Long id){
        //调用方法进行查询
        List list = (List) trainingFeignService.findPaper(id).getData().get("list");
        List<PaperVO> paperVOList = BeanUtil.copyToList(list, PaperVO.class);
        //调用方法封装数据
        paperVOList = toPaperNum(paperVOList);
        return Result.ok().message("查询成功").data("list",paperVOList);
    }

    /**
     * 封装测验数据方法
     * @param paperVOList
     * @return
     */
    private List<PaperVO> toPaperNum(List<PaperVO> paperVOList){
        for (int i = 0; i < paperVOList.size(); i++) {
            PaperVO paperVO = paperVOList.get(i);
            //多少人参加
            Integer studyNum = trainingFeignService.paperMemberNum(paperVO.getId());
            paperVO.setStudyNum(studyNum);
            //多少道题
            Integer questionsNum = paperFeignService.paperQuestionsNum(paperVO.getId());
            paperVO.setQuestionsNum(questionsNum);
            paperVOList.set(i,paperVO);
        }
        return paperVOList;
    }

    /**
     * 根据培训id查询课程方法
     * @param id
     * @return 课程集合 result.data.key -> list
     */
    @RequestMapping(value = "/findCourse",method = RequestMethod.GET)
    public Result findCourse(Long id, HttpServletRequest request){
        //调用方法进行查询
        Result result = trainingFeignService.findCourse(id);
        List list = (List) result.getData().get("list");
        List<CourseVO> courseVOList = BeanUtil.copyToList(list, CourseVO.class);
        //查询学习进度方法
        String token = request.getHeader("token");
        Member member = JSONUtil.toBean(String.valueOf(redisTemplate.opsForValue().get(token)), Member.class);
        courseVOList = toCourseNum(courseVOList,member.getId());
        return Result.ok().message("查询成功").data("list",courseVOList);
    }

    /**
     * 通过成员id查询订阅课程
     * @param memberId
     * @return
     */
    @RequestMapping(value = "/toMemberCourse",method = RequestMethod.GET)
    public Result toMemberCourse(Long memberId,String courseName){
        //调用方法进行查询
        CourseDTO courseDTO = new CourseDTO();
        courseDTO.setCourseName(courseName);
        courseDTO.setPageSize(1000);
        //所有课程集合
        PageInfo<CourseVO> pageInfo = courseFeignService.list(courseDTO);
        List<CourseVO> list = pageInfo.getList();
        list = toCourseNum(list,memberId);
        //订阅课程id
        List courseList = (List) trainingFeignService.toMemberCourse(memberId).getData().get("courseIds");
        String courseIds = StringUtils.join(courseList, ",");
        list = list.stream().filter(i -> courseIds.contains(i.getId()+"")).collect(Collectors.toList());
        pageInfo.setList(list);
        return Result.ok().message("查询成功").data("memberCourse",pageInfo);
    }

    /**
     * 封装课程数据方法
     * @param list
     * @param memberId
     * @return
     */
    private List<CourseVO> toCourseNum(List<CourseVO> list,Long memberId){
        //课程点赞信息
        Map<String,Integer> map = redisTemplate.opsForHash().entries("likeCourse");
        //封装课程数据
        for (int i = 0; i < list.size(); i++) {
            CourseVO vo = list.get(i);
            List catalogIds = (List) courseDetailsFeignService.findCatalogByMemberId(memberId, vo.getId()).getData().get("catalogIds");
            List catalogs = (List) courseDetailsFeignService.findAllCatalog(vo.getId()).getData().get("list");
            List<CatalogVO> catalogVOS = BeanUtil.copyToList(catalogs, CatalogVO.class);
            Double catalogNum = 0.0;
            for (CatalogVO catalogVo : catalogVOS) {
                catalogNum += catalogVo.getChildren().size();
            }
            if (catalogNum != 0){
                vo.setStudyPlan(Double.valueOf(NumberUtil.roundStr(catalogIds.size()/catalogNum * 100,2)));
            }else {
                vo.setStudyPlan(0.0);
            }
            Integer likeNum = map.get(vo.getId().toString());
            vo.setLikeNumber(likeNum);
            vo.setStudyNum(trainingFeignService.toCourseStudyNum(vo.getId()));
            list.set(i,vo);
        }
        return list;
    }

    /**
     * 添加中间表方法
     * @param trainingMember
     * @return
     */
    @RequestMapping(value = "/saveTM",method = RequestMethod.POST)
    public Result saveTM(@RequestBody TrainingMember trainingMember){
        //调用方法进行查询
        Result result = trainingFeignService.saveTM(trainingMember);
        if (result.getSuccess()){
            return result.message("已报名");
        }
        return result;
    }

    /**
     * 根据培训id查询中间表信息
     * @param trainingId
     * @return
     */
    @RequestMapping(value = "/findTM",method = RequestMethod.GET)
    public Result findTM(Long trainingId){
        //调用方法进行查询
        List<TrainingMember> trainingMemberList = trainingFeignService.findTM(trainingId);
        List<Long> list = trainingMemberList.stream().map(TrainingMember::getMemberId).collect(Collectors.toList());
        return Result.ok().message("查询成功").data("mids",list);
    }

    /**
     * 根据id查询培训详情方法
     * @param id
     * @return
     */
    @RequestMapping(value = "/findById",method = RequestMethod.GET)
    public Result findById(Long id){
        //调用方法查询所有培训信息
        TrainingDTO trainingDTO = new TrainingDTO();
        trainingDTO.setPageSize(1000);
        List<TrainingVO> list = trainingFeignService.list(trainingDTO).getList();
        //根据id查询培训信息
        TrainingVO vo = list.stream().filter(i -> i.getId().equals(id)).findAny().get();
        //封装学习人数
        Integer studyNum = trainingFeignService.trainingMemberNum(vo.getId());
        //封装多少课程
        Integer courseNum = trainingFeignService.trainingForCourseNum(vo.getId());
        //封装多少测验
        Integer paperNum = trainingFeignService.trainingPaperNum(vo.getId());
        //获取当前时间
        Date now = new Date();
        if (now.before(vo.getTrainingStartDate())) {
            vo.setTrainingPlan("1");
        } else if (now.equals(vo.getTrainingStartDate()) || now.before(vo.getTrainingEndDate())) {
            vo.setTrainingPlan("2");
        } else {
            vo.setTrainingPlan("3");
        }
        vo.setPaperNum(paperNum);
        vo.setCourseNum(courseNum);
        vo.setStudyNum(studyNum);
        return Result.ok().message("查询成功").data("training",vo);
    }
}
